---
redirect_from:
  - /recipes/using-different-schemas-for-tenants
---

# Using different data models for tenants

## Use case

We want to provide different data models to different tenants. In the recipe
below, we'll learn how to switch between multiple data models based on the
tenant.

## Configuration

We have a folder structure as follows:

```tree
model/
├── avocado/
│   └── cubes
│       └── Products.js
└── mango/
    └── cubes
        └── Products.js
```

Let's configure Cube to use a specific data model path for each tenant. We'll
pass the tenant name as a part of [`securityContext`](/product/auth/context#top)
into the
[`repositoryFactory`](/reference/configuration/config#repositoryfactory)
function.

We'll also need to override the
[`contextToAppId`](/reference/configuration/config#contexttoappid) function to
control how the data model compilation result is cached and provide the tenant
names via the
[`scheduledRefreshContexts`](/reference/configuration/config#scheduledrefreshcontexts)
function so a refresh worker can find all existing data models and build
pre-aggregations for them, if needed.

Our `cube.js` file will look like this:

```javascript
const { FileRepository } = require("@cubejs-backend/server-core");

module.exports = {
  contextToAppId: ({ securityContext }) =>
    `CUBE_APP_${securityContext.tenant}`,

  repositoryFactory: ({ securityContext }) =>
    new FileRepository(`model/${securityContext.tenant}`),

  scheduledRefreshContexts: () => [
    { securityContext: { tenant: "avocado" } },
    { securityContext: { tenant: "mango" } },
  ],
};
```

## Data modeling

In this example, we'd like to get products with odd `id` values for the
`avocado` tenant and with even `id` values the `mango` tenant:

This is the `products` cube for the `avocado` tenant:

<CodeTabs>

```yaml
cubes:
  - name: products
    sql: >
      SELECT * FROM public.Products WHERE MOD (id, 2) = 1
```

```javascript
cube(`products`, {
  sql: `SELECT *
    FROM public.Products
    WHERE MOD (id, 2) = 1`,

  // ...
});
```

</CodeTabs>

This is the `products` cube for the `mango` tenant:

<CodeTabs>

```yaml
cubes:
  - name: products
    sql: >
      SELECT * FROM public.Products WHERE MOD (id, 2) = 0
```

```javascript
cube(`products`, {
  sql: `SELECT *
    FROM public.Products
    WHERE MOD (id, 2) = 0`,

  // ...
});
```

</CodeTabs>

## Query

To fetch the products, we will send two identical queries with different JWTs:

```json
{
  "sub": "1234567890",
  "tenant": "Avocado",
  "iat": 1000000000,
  "exp": 5000000000
}
```

```json5
{
  sub: "1234567890",
  tenant: "Mango",
  iat: 1000000000,
  exp: 5000000000,
}
```

## Result

We will receive different data for each tenant, as expected:

```json5
// Avocado products
[
  {
    "products.id": 1,
    "products.name": "Generic Fresh Keyboard",
  },
  {
    "products.id": 3,
    "products.name": "Practical Wooden Keyboard",
  },
  {
    "products.id": 5,
    "products.name": "Handcrafted Rubber Chicken",
  },
]
```

```json5
// Mango products:
[
  {
    "products.id": 2,
    "products.name": "Gorgeous Cotton Sausages",
  },
  {
    "products.id": 4,
    "products.name": "Handmade Wooden Soap",
  },
  {
    "products.id": 6,
    "products.name": "Handcrafted Plastic Chair",
  },
]
```

## Source code

Please feel free to check out the
[full source code](https://github.com/cube-js/cube/tree/master/examples/recipes/using-different-schemas-for-tenants)
or run it with the `docker-compose up` command. You'll see the result, including
queried data, in the console.
